/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Precipicio;

import java.util.Vector;

/**
 *
 * @author jefferpc
 */
public class ArbolMinMaxPrecipicio {
    int estadoMIN,estadoMAX,cantEscalones;
    boolean cedeTurnoMAX,cedeTurnoMIN;
    Vector <Nodo> pila;
    Vector <Nodo> nodosExpandidos;

    public void calcularUtilidad(Nodo hoja)
    {
        int tamanoArbol=(2*(cantEscalones-estadoMAX))+(2*(cantEscalones-estadoMIN))+1;
        if((hoja.getEstadoJuegoMAX()>hoja.getEstadoJuegoMIN()&&hoja.getEstadoJuegoMAX()<=cantEscalones)||(hoja.getEstadoJuegoMAX() < hoja.getEstadoJuegoMIN()&&hoja.getEstadoJuegoMIN()>cantEscalones&&hoja.getEstadoJuegoMAX() <= cantEscalones))
        {
            //System.out.println((double)(tamanoArbol-hoja.getProfundidad()));
            hoja.setUtilidad((double)(tamanoArbol-hoja.getProfundidad()),"");
        }
        else if((hoja.getEstadoJuegoMAX() < hoja.getEstadoJuegoMIN()&&hoja.getEstadoJuegoMIN()<=cantEscalones)||(hoja.getEstadoJuegoMAX()>hoja.getEstadoJuegoMIN()&&hoja.getEstadoJuegoMAX()>cantEscalones)&&hoja.getEstadoJuegoMIN() <= cantEscalones)
        {//System.out.println(((double)(tamanoArbol-hoja.getProfundidad()))*(-1));
            hoja.setUtilidad(((double)(tamanoArbol-hoja.getProfundidad()))*(-1), "");
        }
        else if(hoja.getEstadoJuegoMAX() == hoja.getEstadoJuegoMIN()||(hoja.getEstadoJuegoMIN()>cantEscalones&&hoja.getEstadoJuegoMAX()>cantEscalones))
        {
            //System.out.println(0);
            hoja.setUtilidad((double)(0),"");
        }
        else
        {
            System .out.println("LA HOJA ES UN DADO");
        }
    }
   public void inicializar(int estadoMAX,int estadoMIN,boolean cedeMAX,boolean cedeMIN)
    {
        pila=new Vector<Nodo>();
        this.cedeTurnoMAX=cedeMAX;
        this.cedeTurnoMIN=cedeMIN;
        nodosExpandidos=new Vector<Nodo>();
        setEstado(estadoMAX,estadoMIN);
   }
   public String tomarDecision()
    {
       String decision="";
       Nodo cabezaPila=null;
       pila.add(new Nodo("MAX", null,0));
       cabezaPila=pila.firstElement();
       cabezaPila.setEstadoJuego(estadoMAX, estadoMIN);
       cabezaPila.setCedeTurnoMax(cedeTurnoMAX);
       cabezaPila.setCedeTurnoMin(cedeTurnoMIN);
       while(pila.size()>0)
       {
           
            cabezaPila=pila.firstElement();
            //System.out.println(cabezaPila.getProfundidad());
            if(termino(cabezaPila))
            {
                calcularUtilidad(cabezaPila);
            }
            else
            {
                //expandir
                if(cabezaPila.getNombre().equals("MAX"))
                {
                    
                    if(!cabezaPila.getCedeTurnoMax())
                    {
                        //Tiro dado
                        Nodo dado=new Nodo("DADO", cabezaPila, cabezaPila.getProfundidad()+1);
                        dado.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        dado.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        dado.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN());
                        pila.add(dado);
                        //cedo el turno
                        Nodo nuevo=new Nodo("MIN", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo.setCedeTurnoMax(true);
                        nuevo.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        nuevo.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN());
                        pila.add(nuevo);
                    }
                    else
                    {
                        Nodo nuevo=new Nodo("MIN", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        nuevo.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        nuevo.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN());
                        pila.add(nuevo);
                    }
                }
                if(cabezaPila.getNombre().equals("MIN"))
                {
                    
                    if(!cabezaPila.getCedeTurnoMin())
                    {
                        //Tiro dado
                        Nodo dado=new Nodo("DADO", cabezaPila, cabezaPila.getProfundidad()+1);
                        dado.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        dado.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        dado.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN());
                        pila.add(dado);
                        //cedo el turno
                        Nodo nuevo=new Nodo("MAX", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        nuevo.setCedeTurnoMin(true);
                        nuevo.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN());
                        pila.add(nuevo);
                    }
                    else
                    {
                        Nodo nuevo=new Nodo("MAX", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        nuevo.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        nuevo.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN());
                        pila.add(nuevo);
                    }
                }
                if(cabezaPila.getNombre().equals("DADO"))
                {
                    if(cabezaPila.getPadre().getNombre().equals("MAX"))
                    {
                        Nodo nuevo=new Nodo("MIN", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        nuevo.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        nuevo.setEstadoJuego(cabezaPila.getEstadoJuegoMAX()+3, cabezaPila.getEstadoJuegoMIN());
                        pila.add(nuevo);
                        Nodo nuevo1=new Nodo("MIN", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo1.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        nuevo1.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        nuevo1.setEstadoJuego(cabezaPila.getEstadoJuegoMAX()+2, cabezaPila.getEstadoJuegoMIN());
                        pila.add(nuevo1);
                        Nodo  nuevo2=new Nodo("MIN", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo2.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        nuevo2.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        nuevo2.setEstadoJuego(cabezaPila.getEstadoJuegoMAX()+1, cabezaPila.getEstadoJuegoMIN());
                        pila.add(nuevo2);
                    }
                    if(cabezaPila.getPadre().getNombre().equals("MIN"))
                    {
                        Nodo nuevo=new Nodo("MAX", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        nuevo.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        nuevo.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN()+3);
                        pila.add(nuevo);
                        Nodo nuevo1=new Nodo("MAX", cabezaPila, cabezaPila.getProfundidad()+1);
                         nuevo1.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                         nuevo1.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                         nuevo1.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN()+2);
                        pila.add(nuevo1);
                        Nodo nuevo2=new Nodo("MAX", cabezaPila, cabezaPila.getProfundidad()+1);
                        nuevo2.setCedeTurnoMax(cabezaPila.getCedeTurnoMax());
                        nuevo2.setCedeTurnoMin(cabezaPila.getCedeTurnoMin());
                        nuevo2.setEstadoJuego(cabezaPila.getEstadoJuegoMAX(), cabezaPila.getEstadoJuegoMIN()+1);
                        pila.add(nuevo2);
                    }
                }
            }
            //System.out.println("CAbezza"+cabezaPila.getNombre()+" "+cabezaPila.getUtilidad()+" "+cabezaPila.getProfundidad()+" "+cabezaPila.getEstadoJuego());
            insertarNodo(cabezaPila);
            pila.remove(cabezaPila);
            
            
       }
       //int x=nodosExpandidos.elementAt(0).getProfundidad();
       for(int i=0;i<nodosExpandidos.size();i++)
       {
           /*if(x!=nodosExpandidos.elementAt(i).getProfundidad())
           {
               x=nodosExpandidos.elementAt(i).getProfundidad();
               System.out.println();
           }*/
           //System.out.println(nodosExpandidos.elementAt(i).getProfundidad());
           nodosExpandidos.elementAt(i).reportarUtilidadPadre();
           //System.out.print(nodosExpandidos.elementAt(i).getEstadoJuego()+"=>"+nodosExpandidos.elementAt(i).getUtilidad()+"\t");

       }
       decision=nodosExpandidos.lastElement().getDecision();
       //    System.out.println(cabezaPila.getUtilidad());

       return decision;
   }

    public void insertarNodo(Nodo nuevoNodo)
    {
        int pos=0;
        /*for(int i=0;i<nodosExpandidos.size();i++)
        {
            if(nodosExpandidos.elementAt(i).getProfundidad()<nuevoNodo.getProfundidad())
            {
                pos=i; break;
            }
        }*/
        nodosExpandidos.add(pos, nuevoNodo);



    }
    public boolean termino(Nodo tmp)
    {
        /*if(tmp.getProfundidad()>20)
            return true;*/
        if(tmp.getCedeTurnoMin())
        {
            if((tmp.getCedeTurnoMax()))
                return true;
            if(tmp.getEstadoJuegoMAX()>=cantEscalones)
                return true;
            if(tmp.getEstadoJuegoMAX()>tmp.getEstadoJuegoMIN())
                return true;
        }
        if(tmp.getCedeTurnoMax())
        {
            if((tmp.getCedeTurnoMin()))
                return true;
            if(tmp.getEstadoJuegoMIN()>=cantEscalones)
                return true;
            if(tmp.getEstadoJuegoMIN()>tmp.getEstadoJuegoMAX())
                return true;
        }
        if(tmp.getEstadoJuegoMAX()>=cantEscalones||tmp.getEstadoJuegoMIN()>cantEscalones)
            return true;
       

        return false;
    }
    

    public void setEstado(int estadoMAX,int estadoMIN) {
        this.estadoMAX = estadoMAX;
        this.estadoMIN = estadoMIN;
    }

    public int getCantEscalones() {
        return cantEscalones;
    }

    public void setCantEscalones(int cantEscalones) {
        this.cantEscalones = cantEscalones;
    }

}
